# 静态算法：根据基础流量确定路由路径，即使之后发生了流量变化，走的路径依旧不会再发生变化
import numpy as np
import json
from topo1 import build_hybrid_topology_shared_tor
from switchesalgo import allocate_switches_with_es


def load_traffic_matrix(filename, target_timestamps):
    """从JSON文件加载指定时间戳的流量矩阵"""
    traffic_data = {}
    with open(filename, 'r') as f:
        data = json.load(f)
        for record in data:
            ts = record['timestamp']
            if ts in target_timestamps:
                matrix = np.array(record['matrix'])
                traffic_data[ts] = matrix
    return traffic_data


def convert_matrix_to_pairs(matrix, node_prefix="ToR"):
    """将流量矩阵转换为通信对字典（自动转换节点命名和类型）"""
    pairs_dict = {}
    rows, cols = matrix.shape
    for i in range(rows):
        for j in range(cols):
            src = f"{node_prefix}{i + 1}"
            dst = f"{node_prefix}{j + 1}"
            pairs_dict[(src, dst)] = float(matrix[i][j])
    return pairs_dict


def generate_traffic_pairs(traffic_dict, min_demand=0):
    """生成有效通信对列表（需求大于阈值）"""
    return [pair for pair, demand in traffic_dict.items() if demand > min_demand]


def calculate_max_delay(traffic_pairs, path_dict, demand_dict, topology):
    """计算给定流量集的最大延迟"""
    max_delay = 0
    for pair in traffic_pairs:
        path = path_dict.get(pair, [])
        if not path:
            continue

        min_capacity = float('inf')
        # 遍历路径中的每条链路
        for i in range(len(path) - 1):
            u, v = path[i], path[i + 1]
            if topology.has_edge(u, v):
                capacity = topology[u][v]['capacity']
                min_capacity = min(min_capacity, capacity)

        if min_capacity > 0:
            pair_delay = demand_dict[pair] / min_capacity
            max_delay = max(max_delay, pair_delay)
    return max_delay


def identify_electric_pairs(traffic_pairs, path_dict, topology):
    """识别需要更新电层路径的通信对"""
    electric_pairs = []
    for pair in traffic_pairs:
        path = path_dict.get(pair, [])
        all_electric = True

        for i in range(len(path) - 1):
            u, v = path[i], path[i + 1]
            if topology[u][v]['type'] != 'electrical':
                all_electric = False
                break

        if all_electric:
            electric_pairs.append(pair)
    return electric_pairs


if __name__ == "__main__":
    # 初始化网络拓扑
    G = build_hybrid_topology_shared_tor(num_tor=4)
    print("拓扑节点:", G.nodes())
    print("拓扑链路:", G.edges(data=True))

    # 加载流量数据
    traffic_data = load_traffic_matrix(
        'traffic_simulation.json',
        target_timestamps=[0.12, 5.19]
    )

    # 处理基础流量
    base_matrix = traffic_data[0.12]
    base_traffic = convert_matrix_to_pairs(base_matrix)
    base_pairs = generate_traffic_pairs(base_traffic)

    # 处理混合流量
    burst_matrix = traffic_data[5.19]
    hybrid_traffic = convert_matrix_to_pairs(burst_matrix)
    hybrid_pairs = generate_traffic_pairs(hybrid_traffic)

    # 路径计算配置
    tor_nodes = {f"ToR{i + 1}" for i in range(4)}
    os_nodes = {f"os{i + 1}" for i in range(4)}

    # 基础流量路径分配
    switches, base_paths = allocate_switches_with_es(
        G, base_pairs, base_traffic,
        tor_nodes, os_nodes, 18
    )

    # 静态路由延迟计算
    static_delay = calculate_max_delay(
        hybrid_pairs, base_paths,
        hybrid_traffic, G
    )
    print(f"\n静态路由最大延迟: {static_delay:.4f} ms")

    # 半静态路由优化
    electric_pairs = identify_electric_pairs(
        hybrid_pairs, base_paths, G
    )
    print(f"需要更新的电层路径: {electric_pairs}")

